<template>
  <div>
    <Upload
      ref="upload"
      multiple
      type="drag"
      action=""
      :format="['jpg','jpeg','png']"
      :default-file-list="defaultFileList"
      :max-size="maxSize"
      :before-upload="fnBeforeUpload"
      :on-remove="fnFileRemove"
      :disabled="inUpload"
    >
      <div style="padding: 20px 0">
        <Icon type="ios-cloud-upload" size="52" style="color: #3399ff" />
        <p>将文件拖到此处，或点击上传</p>
      </div>
      <template #tip>
        <slot name="tip" />
      </template>
    </Upload>
    <Spin v-if="inUpload" size="large" fix />
  </div>

</template>

<script>
import { renderSize } from '@/utils'
import dayjs from 'dayjs'
import ossUploadUtil from '@/utils/ossUploadUtil'
export default {
  name: '',

  components: {},

  mixins: [],

  props: {
    accept: {
      type: Array,
      required: true
    },
    bucketName: {
      type: String,
      default: 'MARTECH'
    },
    folderName: {
      type: String,
      default: '/'
    },
    needRelativePath: {
      type: Boolean,
      default: false
    },
    defaultFileList: {
      type: Array
    },
    tip: {
      type: String
    },
    limit: {
      type: Number,
      default: 1
    },
    maxSize: {
      type: Number,
      default: 10240 // 文件大小限制，单位 kb
    }
  },

  data() {
    return {
      uploadQueue: [], // 上传队列
      inUpload: false // 是否在上传中
    }
  },

  computed: {},

  watch: {},

  created() {},

  mounted() {
  },

  destroyed() {},

  methods: {
    /**
     * @Description: 文件上传前钩子
     * @author tangyuhui
     * @date 2021/5/5 12:03 下午
    */
    fnBeforeUpload(file) {
      if (this.validFile(file)) {
        this.customUpload(file)
      }
      return false
    },
    /**
     * @Description: 验证文件
     * @author tangyuhui
     * @date 2021/5/5 8:25 下午
    */
    validFile(file) {
      // 验证文件格式
      const fileName = file.name
      const allowType = this.accept // 获取文件后缀名
      const fileTypename = fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length)
      const isAcceptFile = allowType.find((type) => type === fileTypename)

      if (this.defaultFileList && this.defaultFileList.length >= this.limit) {
        this.showModalError('提示', `只能上传${this.limit}个文件`)
        return false
      }

      if (!isAcceptFile) {
        this.showModalError('提示', `上传文件格式不能为.${fileTypename}`)
        return false
      }

      // 验证文件大小
      const isLtSize = file.size / 1024 <= this.maxSize
      if (!isLtSize) {
        this.showModalError('提示', '上传文件大小不能超过' + this.maxSize + 'kb')
        return false
      }

      return true
    },
    /**
     * @Description: 自定义上传
     * @author tangyuhui
     * @date 2021/5/5 6:27 下午
    */
    customUpload(file) {
      this.setUploadStatus(true)
      this.uploadQueue.push(file)
      const point = file.name.lastIndexOf('.')
      const suffix = file.name.substr(point)
      let fileName = file.name.substr(0, point)
      fileName = fileName.replace(/[#%]/g, '')
      const date = dayjs().format('YYYYMMDDHHmm')
      const fileNames = `${fileName}_${date}${suffix}`
      file.fileNames = fileNames
      ossUploadUtil.uploadToOss({ bizKey: this.bucketName, folderName: this.folderName, file: file, fileName: fileNames }).then(res => {
        this.handleFileSuccess(file, res)
      }).catch((err) => {
        this.handleFileError(file)
        if (typeof err === 'string') {
          this.showError(err)
        } else {
          this.showError(fileNames + '上传失败，请重试')
        }
      })
    },
    /**
     * @Description: 处理文件上传失败
     * @author tangyuhui
     * @date 2021/5/5 6:50 下午
    */
    handleFileError(file) {
      // 先从上传队列中移除这个元素
      this.removeUploadElement(file)
      // 如果目前已经没有上传元素了
      if (!this.uploadQueue || this.uploadQueue.length === 0) {
        this.setUploadStatus(false)
      }
    },
    handleFileSuccess(file, response) {
      // 先从上传队列中移除这个元素
      this.removeUploadElement(file)
      const ossUrl = response && response.res && response.res.requestUrls && response.res.requestUrls[0]
      const fileObj = {}
      const fileName = file.name
      fileObj.name = fileName
      fileObj.url = ossUrl
      fileObj.size = renderSize(file.size)
      this.$emit('fnUploadSucess', fileObj)
      // eslint-disable-next-line vue/no-mutating-props
      this.defaultFileList.push({
        name: fileName,
        url: ossUrl
      })
      if (!this.uploadQueue || this.uploadQueue.length === 0) {
        this.setUploadStatus(false)
      }
    },
    /**
     * @Description: 移除上传元素
     * @author tangyuhui
     * @date 2021/5/5 6:54 下午
    */
    removeUploadElement(file) {
      // 找到索引
      const index = this.uploadQueue.findIndex(item => item.fileNames === file.fileNames)
      if (index >= 0) {
        this.uploadQueue.splice(index, 1)
      }
    },
    /**
     * @Description: 处理文件移除ßß
     * @author tangyuhui
     * @date 2021/5/5 8:06 下午
    */
    fnFileRemove(file, fileList) {
      const index = this.defaultFileList.findIndex(item => item.url === file.url)
      // eslint-disable-next-line vue/no-mutating-props
      this.defaultFileList.splice(index, 1)
      console.log(this.defaultFileList)
    },
    /**
     * @Description: 设置文件上传状态
     * @author tangyuhui
     * @date 2021/5/5 12:04 下午
     */
    setUploadStatus(flag) {
      this.inUpload = flag
      this.$emit('inUpload', flag)
    }
  }
}
</script>

<style scoped lang="scss">

</style>
